home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: D3DEnum.cpp
- //
- // Desc: Functions to enumerate DDraw/D3D drivers, devices, and modes.
- //
- // Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved
- //-----------------------------------------------------------------------------
- #define STRICT
- #include <windowsx.h>
- #include <stdio.h>
-
- // Includes D3D
- #define D3D_OVERLOADS
- #include <ddraw.h>
- #include <d3d.h>
- #include <d3dx.h>
-
- // Includes utilitaires D3D
- #include "D3DEnum.h"
- #include "d3dmath.h"
- #include "d3dutil.h"
-
- // Ids Resources
- #include "resource.h"
-
- // Constantes
- #include "const.h"
-
- // Types
- #include "types.h"
-
- // Variables globales projet
- #include "vars.h"
-
- // Prototypes fonctions autres modules
- #include "proto.h"
-
- // Macros
- #include "macros.h"
-
- //-----------------------------------------------------------------------------
- // Global data for the enumerator functions
- //-----------------------------------------------------------------------------
- #ifndef NO3D
- static HRESULT (*g_fnAppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) = NULL;
-
- static D3DEnum_DeviceInfo g_pDeviceList[20];
- static DWORD g_dwNumDevicesEnumerated = 0L;
- static DWORD g_dwNumDevices = 0L;
- //-----------------------------------------------------------------------------
- // Name: DeviceEnumCallback()
- // Desc: Callback function for enumerating devices
- //-----------------------------------------------------------------------------
- static HRESULT WINAPI DeviceEnumCallback( TCHAR* strDesc, TCHAR* strName,
- D3DDEVICEDESC7* pDesc,
- VOID* pParentInfo )
- {
- vTrace(" --> Device n° %d : %s (%s)", ++g_dwNumDevicesEnumerated, strName, strDesc);
-
- D3DEnum_DeviceInfo* pDriverInfo = (D3DEnum_DeviceInfo*)pParentInfo;
- D3DEnum_DeviceInfo* pDeviceInfo = &g_pDeviceList[g_dwNumDevices];
- ZeroMemory( pDeviceInfo, sizeof(D3DEnum_DeviceInfo) );
-
- // Select either the HAL or HEL device desc:
- pDeviceInfo->bHardware = pDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION;
- memcpy( &pDeviceInfo->ddDeviceDesc, pDesc, sizeof(D3DDEVICEDESC7) );
-
- // Bail if the device has no windowed support
- if(!pDriverInfo->bDesktopCompatible)
- return D3DENUMRET_OK;
-
- pDeviceInfo->bDesktopCompatible = TRUE;
-
- // Set up device info for this device
- pDeviceInfo->ddDriverCaps = pDriverInfo->ddDriverCaps;
- pDeviceInfo->ddHELCaps = pDriverInfo->ddHELCaps;
- pDeviceInfo->guidDevice = pDesc->deviceGUID;
- pDeviceInfo->pDeviceGUID = &pDeviceInfo->guidDevice;
-
- // Copy the driver GUID and description for the device
- if( pDriverInfo->pDriverGUID )
- {
- pDeviceInfo->guidDriver = pDriverInfo->guidDriver;
- pDeviceInfo->pDriverGUID = &pDeviceInfo->guidDriver;
- lstrcpyn( pDeviceInfo->strDesc, pDriverInfo->strDesc, 39 );
- }
- else
- {
- pDeviceInfo->pDriverGUID = NULL;
- lstrcpyn( pDeviceInfo->strDesc, strName, 39 );
- }
-
- // Avoid duplicates: only enum HW devices for secondary DDraw drivers.
- if( NULL != pDeviceInfo->pDriverGUID && FALSE == pDeviceInfo->bHardware )
- return D3DENUMRET_OK;
-
- // Give the app a chance to accept or reject this device.
- if( g_fnAppConfirmFn )
- if( FAILED( g_fnAppConfirmFn( &pDeviceInfo->ddDriverCaps,
- &pDeviceInfo->ddDeviceDesc ) ) )
- return D3DENUMRET_OK;
-
-
- // Accept the device and return
- g_dwNumDevices++;
-
- return D3DENUMRET_OK;
- }
-
- //-----------------------------------------------------------------------------
- // Name: DriverEnumCallback()
- // Desc: Callback function for enumerating drivers.
- //-----------------------------------------------------------------------------
- static BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,
- TCHAR* strName, VOID*, HMONITOR )
- {
- D3DEnum_DeviceInfo d3dDeviceInfo;
-
- vTrace(" * Driver %s (%s)", strName, strDesc);
-
- // Copy data to a device info structure
- ZeroMemory( &d3dDeviceInfo, sizeof(d3dDeviceInfo) );
- lstrcpyn( d3dDeviceInfo.strDesc, strDesc, 39 );
- d3dDeviceInfo.ddDriverCaps.dwSize = sizeof(DDCAPS);
- d3dDeviceInfo.ddHELCaps.dwSize = sizeof(DDCAPS);
- lpDD->GetCaps( &d3dDeviceInfo.ddDriverCaps, &d3dDeviceInfo.ddHELCaps );
- if( pGUID )
- {
- d3dDeviceInfo.guidDriver = (*pGUID);
- d3dDeviceInfo.pDriverGUID = &d3dDeviceInfo.guidDriver;
- }
-
- // Record whether the device can render into a desktop window
- if( d3dDeviceInfo.ddDriverCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED )
- if( NULL == d3dDeviceInfo.pDriverGUID )
- d3dDeviceInfo.bDesktopCompatible = TRUE;
-
- // Now, enumerate all the 3D devices
- lpD3D->EnumDevices( DeviceEnumCallback, &d3dDeviceInfo );
-
- return DDENUMRET_OK;
- }
-
- #endif
-
- //-----------------------------------------------------------------------------
- // Name: D3DEnum_EnumerateDevices()
- // Desc: Enumerates all drivers, devices, and modes. The callback function is
- // called each device, to confirm that the device supports the feature
- // set required by the app.
- //-----------------------------------------------------------------------------
- HRESULT D3DEnum_EnumerateDevices( HRESULT (*AppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) )
- {
- #ifndef NO3D
- // Store the device enumeration callback function
- g_fnAppConfirmFn = AppConfirmFn;
-
- // Enumerate drivers, devices, and modes
- DirectDrawEnumerateEx( DriverEnumCallback, NULL,
- DDENUM_ATTACHEDSECONDARYDEVICES |
- DDENUM_DETACHEDSECONDARYDEVICES |
- DDENUM_NONDISPLAYDEVICES );
-
- // Make sure devices were actually enumerated
- if( 0 == g_dwNumDevicesEnumerated )
- {
- vTrace("*** E0005 : Aucun device D3D énuméré");
- return D3DENUMERR_ENUMERATIONFAILED;
- }
- if( 0 == g_dwNumDevices )
- {
- vTrace("*** E0006 : Aucun device D3D accepté");
- return D3DENUMERR_SUGGESTREFRAST;
- }
- #endif
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------
- // Name: D3DEnum_GetDevices()
- // Desc: Returns a ptr to the array of D3DEnum_DeviceInfo structures.
- //-----------------------------------------------------------------------------
- VOID D3DEnum_GetDevices( D3DEnum_DeviceInfo** ppDevices, DWORD* pdwCount )
- {
- #ifndef NO3D
- if( ppDevices )
- (*ppDevices) = g_pDeviceList;
- if( pdwCount )
- (*pdwCount) = g_dwNumDevices;
- #endif
- }
-
- //-----------------------------------------------------------------------------
- // Name: UpdateDialogControls()
- // Desc: Builds the list of devices and modes for the combo boxes in the device
- // select dialog box.
- //-----------------------------------------------------------------------------
- static VOID UpdateDialogControls( HWND hDlg, D3DEnum_DeviceInfo* pCurrentDevice)
- {
- #ifndef NO3D
- // Get access to the enumerated device list
- D3DEnum_DeviceInfo* pDeviceList;
- DWORD dwNumDevices;
- D3DEnum_GetDevices( &pDeviceList, &dwNumDevices );
-
- // Access to UI controls
- HWND hwndDevice = GetDlgItem( hDlg, IDC_DEVICE_COMBO );
-
- // Reset the content in each of the combo boxes
- ComboBox_ResetContent( hwndDevice );
-
- // Add a list of devices to the device combo box
- for( DWORD device = 0; device < dwNumDevices; device++ )
- {
- D3DEnum_DeviceInfo* pDevice = &pDeviceList[device];
-
- // Add device name to the combo box
- DWORD dwItem = ComboBox_AddString( hwndDevice, pDevice->strDesc );
-
- // Set the remaining UI states for the current device
- if( pDevice == pCurrentDevice )
- // Set the combobox selection on the current device
- ComboBox_SetCurSel( hwndDevice, dwItem );
- }
- #endif
- }
-
- //-----------------------------------------------------------------------------
- // Name: ChangeDeviceProc()
- // Desc: Windows message handling function for the device select dialog
- //-----------------------------------------------------------------------------
- #ifndef NO3D
- static BOOL CALLBACK ChangeDeviceProc( HWND hDlg, UINT uiMsg, WPARAM wParam,
- LPARAM lParam )
- {
- static D3DEnum_DeviceInfo** ppDeviceArg;
- static D3DEnum_DeviceInfo* pCurrentDevice;
-
- // Get access to the enumerated device list
- D3DEnum_DeviceInfo* pDeviceList;
- DWORD dwNumDevices;
- D3DEnum_GetDevices( &pDeviceList, &dwNumDevices );
-
- // Handle the initialization message
- if( WM_INITDIALOG == uiMsg )
- {
- // Get the app's current device, passed in as an lParam argument
- ppDeviceArg = (D3DEnum_DeviceInfo**)lParam;
- if( NULL == ppDeviceArg )
- return FALSE;
-
- // Setup temp storage pointers for dialog
- pCurrentDevice = (*ppDeviceArg);
-
- UpdateDialogControls( hDlg, pCurrentDevice);
-
- return TRUE;
- }
- else if( WM_COMMAND == uiMsg )
- {
- HWND hwndDevice = GetDlgItem( hDlg, IDC_DEVICE_COMBO );
-
- // Get current UI state
- DWORD dwDevice = ComboBox_GetCurSel( hwndDevice );
-
- D3DEnum_DeviceInfo* pDevice = &pDeviceList[dwDevice];
-
- if( IDOK == LOWORD(wParam) )
- {
- // Handle the case when the user hits the OK button. Check if any
- // of the options were changed
- if( pDevice != pCurrentDevice)
- {
- // Return the newly selected device and its new properties
- (*ppDeviceArg) = pDevice;
- EndDialog( hDlg, IDOK );
- }
- else
- EndDialog( hDlg, IDCANCEL );
-
- return TRUE;
- }
- else if( IDCANCEL == LOWORD(wParam) )
- {
- // Handle the case when the user hits the Cancel button
- EndDialog( hDlg, IDCANCEL );
- return TRUE;
- }
-
- // Keep the UI current
- UpdateDialogControls( hDlg, &pDeviceList[dwDevice]);
- return TRUE;
- }
-
- return FALSE;
- }
- #endif
-
- //-----------------------------------------------------------------------------
- // Name: D3DEnum_UserChangeDevice()
- // Desc: Pops up a dialog which allows the user to select a new device.
- //-----------------------------------------------------------------------------
- HRESULT D3DEnum_UserChangeDevice( D3DEnum_DeviceInfo** ppDevice )
- {
- #ifndef NO3D
- if( IDOK == DialogBoxParam( hInst,
- MAKEINTRESOURCE(IDD_CHANGEDEVICE),
- GetForegroundWindow(),
- ChangeDeviceProc, (LPARAM)ppDevice ) )
- return S_OK;
-
- return E_FAIL;
- #else
- return S_OK;
- #endif
- }
-
- //-----------------------------------------------------------------------------
- // Name: D3DEnum_SelectDefaultDevice()
- // Desc: Pick a default device, preferably hardware and desktop compatible.
- //-----------------------------------------------------------------------------
- HRESULT D3DEnum_SelectDefaultDevice( D3DEnum_DeviceInfo** ppDevice,
- DWORD dwFlags )
- {
- #ifndef NO3D
- // Check arguments
- if( NULL == ppDevice )
- return E_INVALIDARG;
-
- // Get access to the enumerated device list
- D3DEnum_DeviceInfo* pDeviceList;
- DWORD dwNumDevices;
- D3DEnum_GetDevices( &pDeviceList, &dwNumDevices );
-
- // Look for windowable software, hardware, and hardware TnL devices
- D3DEnum_DeviceInfo* pRefRastDevice = NULL;
- D3DEnum_DeviceInfo* pSoftwareDevice = NULL;
- D3DEnum_DeviceInfo* pHardwareDevice = NULL;
- D3DEnum_DeviceInfo* pHardwareTnLDevice = NULL;
-
- for( DWORD i=0; i<dwNumDevices; i++ )
- {
- if( pDeviceList[i].bDesktopCompatible )
- {
- if( pDeviceList[i].bHardware )
- {
- if( (*pDeviceList[i].pDeviceGUID) == IID_IDirect3DTnLHalDevice )
- pHardwareTnLDevice = &pDeviceList[i];
- else
- pHardwareDevice = &pDeviceList[i];
- }
- else
- {
- if( (*pDeviceList[i].pDeviceGUID) == IID_IDirect3DRefDevice )
- pRefRastDevice = &pDeviceList[i];
- else
- pSoftwareDevice = &pDeviceList[i];
- }
- }
- }
-
- // Prefer a hardware TnL device first, then a non-TnL hardware device, and
- // finally, a software device.
- if( 0 == ( dwFlags & D3DENUM_SOFTWAREONLY ) && pHardwareTnLDevice )
- (*ppDevice) = pHardwareTnLDevice;
- else if( 0 == ( dwFlags & D3DENUM_SOFTWAREONLY ) && pHardwareDevice )
- (*ppDevice) = pHardwareDevice;
- else if( pSoftwareDevice )
- (*ppDevice) = pSoftwareDevice;
- else if( pRefRastDevice )
- (*ppDevice) = pRefRastDevice;
- else
- return D3DENUMERR_NOCOMPATIBLEDEVICES;
- #endif
- return S_OK;
- }
-